﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace NetService
{
    public partial class TcpUdpMessageForm : Form
    {
        public TcpUdpMessageForm()
        {
            InitializeComponent();
        }

        /*
         * \brief 通过tcp/udp协议发送数据
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void SendMessage_Click(object sender, EventArgs e)
        {
            ShowMessageRTb.Text = string.Empty;
            // 通过TCP协议发送数据
            if (IsSendMessageByTcp && !IsSendMessageByUdp)
            {
                //实例化一个TcpListener对象，并初始化为空
                TcpListener tcplistener = null;
                //实例化一个IPAddress对象，用来表示网络IP地址
                IPAddress ipaddress = IPAddress.Parse(TargetAddressTb.Text);
                //定义一个int类型变量，用来存储端口号
                int port = Convert.ToInt32(TargetPortTb.Text);
                tcplistener = new TcpListener(ipaddress, port);     //初始化TcpListener对象
                tcplistener.Start();                                //开始TcpListener侦听
                ShowMessageRTb.Text = "等待连接...\n";
                TcpClient tcpclient = null;                         //实例化一个TcpClient对象，并赋值为空
                if (tcplistener.Pending())                          //判断是否有挂起的连接请求
                {
                    tcpclient = tcplistener.AcceptTcpClient();      //使用AcceptTcpClient初始化TcpClient对象
                }
                else
                {
                    tcpclient = new TcpClient(TargetAddressTb.Text, port); //使用TcpClient的构造函数初始化TcpClient对象
                }
                ShowMessageRTb.Text += "连接成功！\n";
                tcpclient.Close();                                  //关闭TcpClient连接
                tcplistener.Stop();                                 //停止TcpListener侦听
            }
            // 通过UDP协议发送数据
            else if (IsSendMessageByUdp && !IsSendMessageByTcp)
            {
                //实例化UdpClient对象
                UdpClient udpclient = new UdpClient(Convert.ToInt32(TargetPortTb.Text));
                //调用UdpClient对象的Connect建立默认远程主机
                udpclient.Connect(TargetAddressTb.Text, Convert.ToInt32(TargetPortTb.Text));
                //定义一个字节数组，用来存放发送到远程主机的信息
                Byte[] sendBytes = Encoding.Default.GetBytes(SendMessageTb.Text);
                //调用UdpClient对象的Send方法将Udp数据报发送到远程主机
                udpclient.Send(sendBytes, sendBytes.Length);
                //实例化IPEndPoint对象，用来显示响应主机的标识
                IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
                //调用UdpClient对象的Receive方法获得从远程主机返回的Udp数据报
                Byte[] receiveBytes = udpclient.Receive(ref ipendpoint);
                //将获得的Udp数据报转换为字符串形式
                string returnData = Encoding.Default.GetString(receiveBytes);
                ShowMessageRTb.Text = "接收到的信息：" + returnData.ToString();
                //使用IPEndPoint对象的Address和Port属性获得响应主机的IP地址和端口号
                ShowMessageRTb.Text += "\n这条信息来自主机" + ipendpoint.Address.ToString()
                    + "上的" + ipendpoint.Port.ToString() + "端口";
                //关闭UdpClient连接
                udpclient.Close();
            }
        }

        /*
         * \brief 通过udp协议发送数据
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void SendMessageByUdp_Click(object sender, EventArgs e)
        {
            ShowMessageRTb.Text = string.Empty;
            //实例化UdpClient对象
            UdpClient udpclient = new UdpClient(Convert.ToInt32(TargetPortTb.Text));
            //调用UdpClient对象的Connect建立默认远程主机
            udpclient.Connect(TargetAddressTb.Text, Convert.ToInt32(TargetPortTb.Text));
            //定义一个字节数组，用来存放发送到远程主机的信息
            Byte[] sendBytes = Encoding.Default.GetBytes(SendMessageTb.Text);
            //调用UdpClient对象的Send方法将Udp数据报发送到远程主机
            udpclient.Send(sendBytes, sendBytes.Length);
            //实例化IPEndPoint对象，用来显示响应主机的标识
            IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
            //调用UdpClient对象的Receive方法获得从远程主机返回的Udp数据报
            Byte[] receiveBytes = udpclient.Receive(ref ipendpoint);
            //将获得的Udp数据报转换为字符串形式
            string returnData = Encoding.Default.GetString(receiveBytes);
            ShowMessageRTb.Text = "接收到的信息：" + returnData.ToString();
            //使用IPEndPoint对象的Address和Port属性获得响应主机的IP地址和端口号
            ShowMessageRTb.Text += "\n这条信息来自主机" + ipendpoint.Address.ToString()
                + "上的" + ipendpoint.Port.ToString() + "端口";
            //关闭UdpClient连接
            udpclient.Close();
        }

        /*
         * \brief 通过tcp协议发送数据
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void SendMessageByTcp_Click(object sender, EventArgs e)
        {
            //实例化一个TcpListener对象，并初始化为空
            TcpListener tcplistener = null;
            //实例化一个IPAddress对象，用来表示网络IP地址
            IPAddress ipaddress = IPAddress.Parse(TargetAddressTb.Text);
            //定义一个int类型变量，用来存储端口号
            int port = Convert.ToInt32(TargetPortTb.Text);
            tcplistener = new TcpListener(ipaddress, port);     //初始化TcpListener对象
            tcplistener.Start();                                //开始TcpListener侦听
            ShowMessageRTb.Text = "等待连接...\n";
            TcpClient tcpclient = null;                         //实例化一个TcpClient对象，并赋值为空
            if (tcplistener.Pending())                          //判断是否有挂起的连接请求
            {
                tcpclient = tcplistener.AcceptTcpClient();      //使用AcceptTcpClient初始化TcpClient对象
            }
            else
            {
                tcpclient = new TcpClient(TargetAddressTb.Text, port); //使用TcpClient的构造函数初始化TcpClient对象
            }
            ShowMessageRTb.Text += "连接成功！\n";
            tcpclient.Close();                                  //关闭TcpClient连接
            tcplistener.Stop();                                 //停止TcpListener侦听
        }

        /*
         * \brief 信息发送方式变更
         * 
         * \param sender  获取响应物体
         * \param e 响应事件
         */
        private void SendMessageType_CheckedChanged(object sender, EventArgs e)
        {
            string controlName = (sender as RadioButton).Name;
            if (controlName == "TCPTypeRB")
            {
                if (IsSendMessageByTcp)
                {
                    IsSendMessageByUdp = false;
                }
                else
                {
                    IsSendMessageByUdp = true;
                }
            }
            else if (controlName == "UDPTypeRB")
            {
                if (IsSendMessageByUdp)
                {
                    IsSendMessageByTcp = false;
                }
                else
                {
                    IsSendMessageByTcp = true;
                }
            }
            else
            { }
        }

        /*
         * \brief 基于UDP 协议对指定地址发送信息
         * 
         * \param targetAddress  目标地址
         * \param portIndex 对应端口号
         * \param message 发送消息
         * \return returnMessage 返回数据
         */
        public string SendMessageByUdp(string targetAddress, uint portIndex, string message)
        {
            String returnMessage = String.Empty;
            //实例化UdpClient对象
            UdpClient udpclient = new UdpClient((int)portIndex);
            //调用UdpClient对象的Connect建立默认远程主机
            udpclient.Connect(targetAddress, (int)portIndex);
            //定义一个字节数组，用来存放发送到远程主机的信息
            Byte[] sendBytes = Encoding.Default.GetBytes(message);
            //调用UdpClient对象的Send方法将Udp数据报发送到远程主机
            udpclient.Send(sendBytes, sendBytes.Length);
            //实例化IPEndPoint对象，用来显示响应主机的标识
            IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
            //调用UdpClient对象的Receive方法获得从远程主机返回的Udp数据报
            Byte[] receiveBytes = udpclient.Receive(ref ipendpoint);
            //将获得的Udp数据报转换为字符串形式
            returnMessage = String.Format("接收到的信息：{0}", Encoding.Default.GetString(receiveBytes));
            //使用IPEndPoint对象的Address和Port属性获得响应主机的IP地址和端口号
            returnMessage += String.Format("\n这条信息来自主机{0}上的{1}端口", ipendpoint.Address, ipendpoint.Port);
            //关闭UdpClient连接
            udpclient.Close();
            return returnMessage;
        }

        /*
         * \brief 基于TCP 协议对指定地址发送信息
         * 
         * \param targetAddress  目标地址
         * \param portIndex 对应端口号
         * \param message 发送消息
         * \return returnMessage 返回数据
         */
        private string SendMessageByTcp(string targetAddress, uint portIndex, string message)
        {
            String returnMessage = String.Empty;
            //实例化一个TcpListener对象，并初始化为空
            TcpListener tcplistener = null;
            //实例化一个IPAddress对象，用来表示网络IP地址
            IPAddress ipaddress = IPAddress.Parse(targetAddress);
            //定义一个int类型变量，用来存储端口号
            tcplistener = new TcpListener(ipaddress, (int)portIndex);     //初始化TcpListener对象
            tcplistener.Start();                                //开始TcpListener侦听
            returnMessage += "等待连接...\n";
            TcpClient tcpclient = null;                         //实例化一个TcpClient对象，并赋值为空
            if (tcplistener.Pending())                          //判断是否有挂起的连接请求
            {
                tcpclient = tcplistener.AcceptTcpClient();      //使用AcceptTcpClient初始化TcpClient对象
            }
            else
            {
                tcpclient = new TcpClient(returnMessage, (int)portIndex); //使用TcpClient的构造函数初始化TcpClient对象
            }
            returnMessage += "连接成功！\n";
            tcpclient.Close();                                  //关闭TcpClient连接
            tcplistener.Stop();                                 //停止TcpListener侦听
            return  returnMessage;
        }

        // 是否根据TCP协议发送数据
        private bool isSendMessageByTcp = true;
        public bool IsSendMessageByTcp
        {
            get { return isSendMessageByTcp; }
            set
            {
                isSendMessageByTcp = value;
                OnPropertyChanged("IsSendMessageByTcp");
            }
        }

        // 是否根据UDP协议发送数据
        private bool isSendMessageByUdp = true;
        public bool IsSendMessageByUdp
        {
            get { return isSendMessageByUdp; }
            set
            {
                isSendMessageByUdp = value;
                OnPropertyChanged("IsSendMessageByUdp");
            }
        }

        // 属性变化事件
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}